package com.lcy.mapstruct;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONException;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.lcy.enums.ProblemDifficultyEnum;
import com.lcy.model.dto.problem.JudgeCase;
import com.lcy.model.dto.problem.JudgeConfig;
import com.lcy.model.dto.problem.OjProblemRequest;
import com.lcy.model.dto.problem.OjProblemUpdateRequest;
import com.lcy.model.entity.OjProblem;
import com.lcy.model.vo.OjProblemPageVo;
import com.lcy.model.vo.OjProblemVo;
import org.mapstruct.Mapper;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 题目 Mapstruct
 *
 * @author zhang.rx
 * @since 2024/3/20
 */
@Mapper(componentModel = "Spring")
public interface OjProblemConverter {

	static OjProblem addDto2Entity(OjProblemRequest req) {
		String title = req.getTitle();
		String content = req.getContent();
		List<String> tags = req.getTags();
		Integer difficulty = req.getDifficulty();
		String answer = req.getAnswer();
		List<JudgeCase> judgeCase = req.getJudgeCase();
		JudgeConfig judgeConfig = req.getJudgeConfig();

		OjProblem ojProblem = new OjProblem();
		ojProblem.setTitle(title);
		ojProblem.setContent(content);
		if (CollUtil.isNotEmpty(tags)) {
			ojProblem.setTags(JSON.toJSONString(tags));
		}
		ojProblem.setDifficulty(difficulty);
		ojProblem.setAnswer(answer);
		if (CollUtil.isNotEmpty(judgeCase)) {
			ojProblem.setJudgeCase(JSON.toJSONString(judgeCase));
		}
		if (judgeCase != null) {
			ojProblem.setJudgeConfig(JSON.toJSONString(judgeConfig));
		}

		return ojProblem;
	}

	static OjProblem updateDto2Entity(OjProblemUpdateRequest req) {
		Long id = req.getId();
		OjProblem ojProblem = addDto2Entity(req);
		ojProblem.setId(id);
		return ojProblem;
	}

	static OjProblemPageVo entity2VoPage(OjProblem ojProblem) {
		Long id = ojProblem.getId();
		String title = ojProblem.getTitle();
		String content = ojProblem.getContent();
		String tags = ojProblem.getTags();
		Integer difficulty = ojProblem.getDifficulty();
		Integer submitNum = ojProblem.getSubmitNum();
		Integer acceptedNum = ojProblem.getAcceptedNum();
		Integer thumbNum = ojProblem.getThumbNum();
		Integer favourNum = ojProblem.getFavourNum();

		OjProblemPageVo pageVo = new OjProblemPageVo();
		pageVo.setId(id);
		pageVo.setTitle(title);
		pageVo.setContent(content);
		pageVo.setTags(JSONUtil.toList(tags, String.class));
		ProblemDifficultyEnum anEnum = ProblemDifficultyEnum.getEnum(difficulty);
		if (anEnum != null) {
			pageVo.setDifficulty(anEnum.getName());
		}
		pageVo.setSubmitNum(submitNum);
		pageVo.setAcceptedNum(acceptedNum);
		pageVo.setThumbNum(thumbNum);
		pageVo.setFavourNum(favourNum);
		return pageVo;
	}

//	static OjProblemVo entity2Vo(OjProblem ojProblem) {
//		Long id = ojProblem.getId();
//		String title = ojProblem.getTitle();
//		String content = ojProblem.getContent();
//		String tags = ojProblem.getTags();
//		Integer difficulty = ojProblem.getDifficulty();
//		String ansLanguage = ojProblem.getAnsLanguage();
//		String answer = ojProblem.getAnswer();
//		Integer submitNum = ojProblem.getSubmitNum();
//		Integer acceptedNum = ojProblem.getAcceptedNum();
//		String judgeCase = ojProblem.getJudgeCase();
//		String judgeConfig = ojProblem.getJudgeConfig();
//		Integer thumbNum = ojProblem.getThumbNum();
//		Integer favourNum = ojProblem.getFavourNum();
//
//
//		OjProblemVo vo = new OjProblemVo();
//		vo.setId(id);
//		vo.setTitle(title);
//		vo.setContent(content);
//		vo.setTags(JSONUtil.toList(tags, String.class));
//		vo.setDifficulty(difficulty);
//		vo.setSubmitNum(submitNum);
//		vo.setAcceptedNum(acceptedNum);
//		vo.setAnsLanguage(ansLanguage);
//		vo.setAnswer(answer);
//		vo.setJudgeCase(JSONUtil.toList(judgeCase, JudgeCase.class));
//		vo.setJudgeConfig(JSONUtil.toBean(judgeConfig, JudgeConfig.class));
//		vo.setThumbNum(thumbNum);
//		vo.setFavourNum(favourNum);
//		return vo;
//	}
//
//}

	static OjProblemVo entity2Vo(OjProblem ojProblem) {
		Long id = ojProblem.getId();
		String title = ojProblem.getTitle();
		String content = ojProblem.getContent();
		String tags = ojProblem.getTags();
		Integer difficulty = ojProblem.getDifficulty();
		String ansLanguage = ojProblem.getAnsLanguage();
		String answer = ojProblem.getAnswer();
		Integer submitNum = ojProblem.getSubmitNum();
		Integer acceptedNum = ojProblem.getAcceptedNum();
		String judgeCase = ojProblem.getJudgeCase();
		String judgeConfig = ojProblem.getJudgeConfig();
		Integer thumbNum = ojProblem.getThumbNum();
		Integer favourNum = ojProblem.getFavourNum();

		OjProblemVo vo = new OjProblemVo();
		vo.setId(id);
		vo.setTitle(title);
		vo.setContent(content);

		// 处理 tags 字段
		try {
			vo.setTags(parseJsonToList(tags, String.class));
		} catch (Exception e) {
//			log.error("解析 tags JSON 失败: " + tags, e);
			vo.setTags(Collections.emptyList()); // 设置默认值
		}

		vo.setDifficulty(difficulty);
		vo.setSubmitNum(submitNum);
		vo.setAcceptedNum(acceptedNum);
		vo.setAnsLanguage(ansLanguage);
		vo.setAnswer(answer);

		// 处理 judgeCase 字段
		try {
			vo.setJudgeCase(parseJsonToList(judgeCase, JudgeCase.class));
		} catch (Exception e) {
//			log.error("解析 judgeCase JSON 失败: " + judgeCase, e);
			vo.setJudgeCase(Collections.emptyList()); // 设置默认值
		}

		// 处理 judgeConfig 字段
		try {
			vo.setJudgeConfig(JSONUtil.toBean(judgeConfig, JudgeConfig.class));
		} catch (Exception e) {
//			log.error("解析 judgeConfig JSON 失败: " + judgeConfig, e);
			vo.setJudgeConfig(new JudgeConfig()); // 设置默认值
		}

		vo.setThumbNum(thumbNum);
		vo.setFavourNum(favourNum);
		return vo;
	}

	/**
	 * 将 JSON 字符串安全地转换为 List
	 *
	 * @param jsonStr     JSON 字符串
	 * @param elementType List 元素类型
	 * @return 转换后的 List
	 */
	private static <T> List<T> parseJsonToList(String jsonStr, Class<T> elementType) {
		if (jsonStr == null || jsonStr.trim().isEmpty()) {
			return Collections.emptyList();
		}

		// 去除前后空格
		String trimmed = jsonStr.trim();

		// 如果已经是有效的 JSON 数组，直接转换
		if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
			return JSONUtil.toList(trimmed, elementType);
		}

		// 如果是有效的 JSON 对象，包装成数组
		if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
			return JSONUtil.toList("[" + trimmed + "]", elementType);
		}

		// 如果是逗号分隔的字符串（非 JSON 格式）
		if (!trimmed.startsWith("[") && !trimmed.startsWith("{")) {
			// 按逗号分割并去除每个元素的前后空格
			return Arrays.stream(trimmed.split(","))
					.map(String::trim)
					.filter(s -> !s.isEmpty())
					.map(item -> {
						if (elementType == String.class) {
							return (T) item;
						} else {
							return JSONUtil.toBean(item, elementType);
						}
					})
					.collect(Collectors.toList());
		}

		// 其他情况抛出异常
		throw new JSONException("Invalid JSON format: " + jsonStr);
	}
}
